var storage = {
    get:function(key){
        try{
          return JSON.parse(localStorage[key]); 
        }
        catch(e){return ''}
    },
    //synced : server to client
    set:function(key, value, synced){
        try{
            localStorage[key] = JSON.stringify(value);
            !synced && (needSyncStorage = true);
            return true;
        }
        catch(e){return false;}
    }
};

var getNextPageTabId = null, masterTabId = null, needSyncStorage = false, _m = chrome.i18n.getMessage, version, topicAuthor={}, menuID;
var baseUrl = 'http://os.heimali.com/HappyReader/',
    listUrl = baseUrl + 'list.php',
    intfUrl = baseUrl + 'index.php',
	saveUrl = baseUrl + 'save.php',
	downloadUrl = baseUrl + 'download.php',
	welcomeUrl = baseUrl + 'welcome.html',
	updateUrl = baseUrl + 'update_check.html';

/* string url, string data, string type, function callback */
function ajax(url, data, type, callback){
    var type = (type.toLowerCase()=='get') ? 'GET' : 'POST',
        data = data.replace(/\+/g, '*add*'),
        request = new XMLHttpRequest();

    request.open(type, url);
    request.setRequestHeader("Content-type", "application/x-www-form-urlencoded;charset=UTF-8");
    request.onreadystatechange = function() {
        if (!callback)return;
        try {
            if (this.readyState == XMLHttpRequest.DONE) {
                callback(JSON.parse(this.responseText));
            }
        }catch(e){
            callback({suc:'-2', errmsg:'Cloud service is busy !<br/>Please try again later.'})
        }
    };
    request.send(data||null);
}

ajax(chrome.extension.getURL('manifest.json'), '', 'GET', function(manifest){
    version = manifest.version;
	update.check();
});

if(!storage.get('welcomed')) {
    chrome.tabs.create({url:welcomeUrl, selected:true},function(tab){});
	storage.set('welcomed', 1);
}

function callExt(tab, mode){
	chrome.tabs.sendRequest(tab.id, {'callExtMode':mode}, function(response) {});
}

chrome.browserAction.onClicked.addListener(function(tab){
	callExt(tab, 'browseAction');
	//chrome.tabs.sendRequest(tab.id, {'callExtMode':'browseAction'}, function(response) {});
});

chrome.extension.onRequestExternal.addListener(function(request, sender, sendResponse){
    if (sender.id == 'kfbkjmofblefhdbabmjfecidcglggoaa' && request.cmd == 'openWebElement'){
        chrome.tabs.getSelected(undefined, function(tab){
            callExt(tab, 'mouseGesture');
			//chrome.tabs.sendRequest(tab.id, {'callExtMode':'mouseGesture'}, function(response) {});
        })
        sendResponse({});
    }
});

chrome.extension.onRequest.addListener(
    function(request, sender, sendResponse) {
        if (request.action == "sendTextToCloud") {
            sendTextToCloud(request, function(res){
                sendResponse(res);
            });
        }else if (request.action == "downloadText") {
			downloadText(request, function(res){
                sendResponse(res);
            });
		}else if (request.action == "openOptions") {
			 chrome.tabs.create({url:chrome.extension.getURL('options.html')+'?'+request.content, selected:true},function(tab){});
		}
});

chrome.extension.onConnect.addListener(popupConnHandler);
function popupConnHandler(port) {
	port.onMessage.addListener(function(msg){
		if (port.name != 'popupConn')return ;
		switch(msg.action) {
			case 'getUpdateContent':
                var updateInfo = storage.get(update.storageKey);
                port.postMessage({action:msg.action+'Response', value: {
					desc: updateInfo.description,
					ver: updateInfo.version
				}});
                break;
			case 'resetUpdateStatus':
                update.resetStatus();
				break;
		}
	});
}

chrome.extension.onConnect.addListener(copyConnHandler);
function copyConnHandler(port){
	port.onMessage.addListener(function(msg){
        if (port.name != 'copyConn')return ;
		switch(msg.action) {
			case 'copyToClipboard':
			    var text = msg.value, clipboard;
				if (text) {
					clipboard = document.getElementsByTagName('textarea')[0];
					clipboard.value = text;
					clipboard.select();
					document.execCommand('Copy');
				}
				break;
		}
	});
}

//chrome.extension.onConnectExternal.addListener(nextPageConnHandler);
chrome.extension.onConnect.addListener(nextPageConnHandler);
function nextPageConnHandler(port){
	port.onMessage.addListener(function(msg){
		if (port.name != 'nextPageConn')return ;
		//console.assert(port.name == "nextPageConn");
		switch(msg.action) {
			case 'getNextPageContent':
                if (getNextPageTabId === null){
                    chrome.tabs.create({url:msg.url, selected:false},function(tab){
						var tabId = tab.id;
						getNextPageTabId = tabId;
						chrome.tabs.onRemoved.addListener(function(tabId, removeInfo){
							chrome.tabs.connect(masterTabId).postMessage({action: 'cancelNextPageContent'});
                            getNextPageTabId = null;
						});
					});
                    masterTabId = port.sender.tab.id;
                }
                break;
			case 'setNextPageContent':
				chrome.tabs.connect(masterTabId).postMessage({action:'setNextPageContent', content: msg.content});
                break;
			case 'noNextPageContent':
			    chrome.tabs.remove(getNextPageTabId, function(tab){getNextPageTabId=null});
				chrome.tabs.connect(masterTabId).postMessage({action:'noNextPageContent'});
			    break;
			case 'canceledNextPageContent':
			    break;
			case 'getTopicAuthor':
			    var topic = msg.topic;
			    port.postMessage({action:'getTopicAuthorResponse', value:{topic:topic, author:topicAuthor[topic]}});
			    break;
			case 'setTopicAuthor':
			    topicAuthor[msg.value.topic] = msg.value.author;
			    break;
		}
	});
}

//chrome.extension.onConnectExternal.addListener(optionConnHandler);
chrome.extension.onConnect.addListener(optionConnHandler);
function optionConnHandler(port){
	port.onMessage.addListener(function(msg){
		if (port.name != 'optionConn')return ;
		//console.assert(port.name == "optionConn");
		switch(msg.action) {
			case 'setTextSkin':
			    storage.set('setting_textSkin', msg.textSkin);
				//exclude self tab id
                broadcast({action:'updateTextSkin', textSkin:msg.textSkin}, port.sender.tab.id);
			    break;
		}
	});
}

//chrome.extension.onConnectExternal.addListener(guardConnHandler);
chrome.extension.onConnect.addListener(guardConnHandler);
function guardConnHandler(port){
    port.onMessage.addListener(function(msg){
		if (port.name != 'guardConn')return ;
		//console.assert(port.name == "guardConn");
		switch(msg.action) {
			case 'get':
                var guardMsg = getOptions();
	            guardMsg.userInfo = storage.get('user_info');
	            guardMsg.isTabForNextPage = (port.sender.tab.id == getNextPageTabId);
				guardMsg.version = version;
	            port.postMessage(guardMsg);
			    break;
			case 'setOptionsEnableAnalysisHelper':
			    storage.set('options_enableAnalysisHelper', parseInt(msg.value));
			    break;
			case 'setOptionsEnableSuperAutoNextPage':
			    storage.set('options_enableSuperAutoNextPage', parseInt(msg.value));
                break;
			case 'setOptionsEnableShareBtn':
                storage.set('options_enableShareBtn', parseInt(msg.value));
                break;
		}
    });
};

function getOptions(){
    return {
        setting_textSkin: storage.get('setting_textSkin') || {bg:'#fff', fontSize:'16px', pageWidth:'800'},
        options_hotkey: storage.get('options_hotkey'),
        options_enableAnalysisHelper: storage.get('options_enableAnalysisHelper'),
        options_enableSuperAutoNextPage: storage.get('options_enableSuperAutoNextPage'),
		options_enableTabs: storage.get('options_enableTabs')||{Img:1,Text:1,Link:0},
		options_enableShareBtn: storage.get('options_enableShareBtn'),
		options_enableRightMenu: storage.get('options_enableRightMenu'),
		welcomed: storage.get('welcomed')
    };
}

function sendTextToCloud(msg, callback){
    var userInfo = storage.get('user_info');
    if (userInfo.uid) {
        var url = intfUrl + "?type=setArticle&uid=" + userInfo.uid + "&token=" + userInfo.token, 
        data = "surl=" + msg.url + "&mytitle=" + msg.title + "&intro="+ msg.intro +"&content=" + encodeURIComponent(msg.content);
        ajax(url, data, 'POST', callback);
    }else{
        callback({suc:0, msg:'<a href="'+chrome.extension.getURL('options.html')+'" style="color:yellow" target="_blank">'+_m('login')+'</a>'});
    }
}

function downloadText(msg, callback) {
	var userInfo = storage.get('user_info');
    if (userInfo.uid) {
        var url = saveUrl + "?type=txt&uid=" + userInfo.uid + "&token=" + userInfo.token, 
        data = "content=" + encodeURIComponent(msg.content);
        ajax(url, data, 'POST', function(res){
			res['downloadUrl'] = downloadUrl;
			callback(res);
		});
    }else{
        callback({errno:-1, errmsg:'<a href="'+chrome.extension.getURL('options.html')+'" style="color:yellow" target="_blank">'+_m('login')+'</a>'});
    }
}

function syncConfigToCloud(callback) {
	var userInfo = storage.get('user_info');
    if (userInfo.uid) {
        var url = intfUrl+"?type=setConf&uid="+userInfo.uid+"&token="+userInfo.token,
            data = 'conf='+JSON.stringify(getOptions());
        ajax(url, data, 'post',  function(res){if (res.suc) {needSyncStorage = false;} callback && callback(res)});
    }
}

function syncConfigFromCloud() {
	var userInfo = storage.get('user_info');
    if (!userInfo.uid || !userInfo.token)return null;
	var url = intfUrl+"?type=getConf&uid="+userInfo.uid+"&token="+userInfo.token+"&r="+Math.random(1,100000);
	ajax(url, '', 'get', function(res){
        try {
            if(res.suc == '1' && res.data){
				var data = JSON.parse(res.data);
                for (var key in data) {
                    storage.set(key, data[key], true);
                }
				broadcast({action:'syncConfig', value:res.data});
            }
        }catch(e){console.log(e)}
    });
}

syncConfigFromCloud();

function syncLoginInfo() {
	var userInfo = storage.get('user_info');
    if (!userInfo.uid || !userInfo.token)return null;
	broadcast({action:'syncLoginInfo', value:{userInfo: userInfo}});
}

function broadcast(msg, excludeTabID) {
	chrome.tabs.getAllInWindow(null, function(tabs){
        tabs.forEach(function(tab, idx){
            if (!needInjected(tab.url)){
                return ;
            }
			if (excludeTabID == tab.id) {
				return ;
			}
			
            try {
                chrome.tabs.connect(tab.id).postMessage(msg);
            }catch(e){console.log(e)}
        })
    });
}

function needInjected(url) {
	return !((url.indexOf("chrome://")==0) || (url.indexOf("https://chrome.google.com")==0));
}

setInterval(function(){
    needSyncStorage && syncConfigToCloud();
}, 1000*60);

var update = {
	defaultUpdateInfo:{
		status:0, //0 no update; 1 need update
	    version:'',
	    description:'',
	    lastTipTime:''
	},
	checkInterval:86400,
	storageKey:'update_info',
	check:function(){
		var curTime = this.getTime(), 
            updateInfo = storage.get(this.storageKey),
            lastTipTime = (storage.get('update_lastTipTime') || (updateInfo && updateInfo.lastTipTime))|0;
		if (curTime - lastTipTime <= this.checkInterval) {
			if (updateInfo && (updateInfo.version > version)) {
				update.notice();
			}
			return ;
		}
		
		ajax(updateUrl, '', 'GET', function(res){
			if (!res)return;
			var updateInfo = JSON.parse(JSON.stringify(update.defaultUpdateInfo));
			updateInfo.lastTipTime = curTime;
			if (res.ver > version) {
				update.notice();
				updateInfo.status = 1;
				updateInfo.version = res.ver;
				updateInfo.description = res.desc;
			}
			storage.set(update.storageKey, updateInfo, true);
            if (storage.get('update_lastTipTime')) {
                localStorage.removeItem('update_lastTipTime');
            }
		});
	},
	notice:function(){
		update.setTitle(_m('updateIconTip'));
        update.setIcon('img/icon-update-19.png');
        update.setPopup('popup.html');
	},
	getTime:function(){
		return +new Date()/1000|0;
	},
	resetStatus:function(){
		var updateInfo = storage.get(this.storageKey);
		updateInfo.status = 0;
		updateInfo.version = '';
		updateInfo.description = '';
		storage.set(this.storageKey, updateInfo, true);
        this.setTitle(_m('extName'));
        this.setIcon('img/icon-128.png');
        this.setPopup('');
	},
	setIcon:function(url){chrome.browserAction.setIcon({path:chrome.extension.getURL(url)});},
	setTitle:function(text){chrome.browserAction.setTitle({title:text});},
	setPopup:function(url){chrome.browserAction.setPopup({popup:url});}
};

if (storage.get('options_enableRightMenu') === '') {
    storage.set('options_enableRightMenu', 1);
}
if (storage.get('options_enableRightMenu')) {
    initRightMenu();
}

function initRightMenu() {
    menuID = chrome.contextMenus.create({
        title: _m('extName'),
        onclick: function(){
        },
        contexts: ["all"]
    });
    
    chrome.extension.onConnect.addListener(rightMenuConnHandler);
    function rightMenuConnHandler(port){
        port.onMessage.addListener(function(msg){
            if (port.name != 'rightMenuConn') 
                return;
            switch (msg.action) {
                case 'updateRightMenu':
                    var t = msg.selection ? _m('menuSelectionSendTo') : _m('extName');
                    chrome.contextMenus.update(menuID, {
                        title: t,
                        onclick: function(){
                            callExt(port.sender.tab, 'rightMenu');
                        }
                    });
                    break;
            }
        });
    }
}
function destoryRightMenu(){
    chrome.contextMenus.remove(menuID);
}
